import { Application } from "express";
import fs from 'fs';
import path from 'path';
import {MappingMetadata,MAPPGING_KEY,CONTROLLER_KEY} from './_interface'

class ControllerScanner {
    static scanAndRegisterControllers(app: Application,controllersDir:string,contextPath?:string) {
        const controllers: any[] = [];
        this.scanDirectoryForControllers(controllersDir, controllers)
        controllers.forEach(controller => {
            console.log("Controller：",controller)
            const instance = new controller();
            const controllerPath: string = Reflect.getMetadata(CONTROLLER_KEY, controller) || '';
            const methodMappings: MappingMetadata[] = Reflect.getMetadata(MAPPGING_KEY, controller.prototype) || [];
            methodMappings.forEach(mapping => {
                const routeHandler = instance[mapping.handlerName].bind(instance);
                app[mapping.method](buildConfigPath(mapping,controllerPath,contextPath), routeHandler);
            });
        });
    }
        // 递归扫描指定目录，查找带有@Controller装饰器的类
    static scanDirectoryForControllers(dir: string, controllers: any[]) {
        const files = fs.readdirSync(dir);

        files.forEach(file => {
            const fullPath = path.join(dir, file);
            // 排除node_modules目录
            if (fullPath.includes('node_modules')||fullPath.includes('core')) return;
            // 如果是目录，则递归扫描
            if (fs.statSync(fullPath).isDirectory()) {
                this.scanDirectoryForControllers(fullPath, controllers);
            } else if (file.endsWith('.ts') || file.endsWith('.js')) {
                this.scanFileForController(fullPath, controllers);
            }
        });
    }
    // 扫描单个文件，检查是否包含@Controller装饰器
    static scanFileForController(filePath: string, controllers: any[]) {
        const controllerModule = require(filePath);
        Object.keys(controllerModule).forEach(key => {
            const target = controllerModule[key];
            if (Reflect.hasMetadata(CONTROLLER_KEY, target)) {
                controllers.push(target);  // 如果是Controller类，加入到controllers数组中
            }
        });
    }
}
function buildConfigPath(mapping:MappingMetadata,controllerPath?:string,contextPath?:string){
    let controllerContextPath=controllerPath||''
    if(controllerContextPath==='/')controllerContextPath=''
    if(controllerContextPath&&!controllerContextPath.startsWith('/'))controllerContextPath='/'+controllerContextPath
    let path=mapping.path||mapping.handlerName
    if(!path.startsWith("/"))path='/'+path
    if(contextPath){
        if(!contextPath.startsWith("/"))contextPath='/'+contextPath
        return `${contextPath}${controllerContextPath}${path}`
    }
    return `${controllerContextPath}${path}`
}

export default function (app:Application,controllersDir:string,contextPath?:string){
    ControllerScanner.scanAndRegisterControllers(app,controllersDir,contextPath);
}